package com.qqserver.service;

import com.qqcommon.Message;
import com.qqcommon.MessageType;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;

/**
 *
 * 该类的一个对象和客户端保持通信
 */

public class ServerConnectClientThread extends Thread{
    public Socket getSocket() {
        return socket;
    }

    //必须持有socket
    private Socket socket;
    private String userId;//连接到服务器端的用户的用户名
    public ServerConnectClientThread(Socket socket, String userId) {
        this.socket = socket;
        this.userId = userId;
    }

    //用户上线后,遍历离线消息集合
    public void online(){
        //遍历消息
        //判断离线消息中是否有其狗名
        ArrayList<Message>messages=OffLineMessage.getArrayList(userId);
        if(messages!=null) {//为空则没有我的消息
            //有消息则取消息

                for(int i=0;i<messages.size();i++){
                    try {
                        ObjectOutputStream oos = new ObjectOutputStream(ManageServerConnectClientThread.getServerConnectClientThread(userId).getSocket().getOutputStream());
                        oos.writeObject(messages.get(i));
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            //发送完离线消息,则remove
            OffLineMessage.remove(userId);
        }
            //为空则没有我的消息,不用处理
    }

    @Override
    public void run() {
        while(true){
            try {
                online();//先判断有无离线消息
                System.out.println("服务端和客户端"+ userId+"保持通信,读取数据....");
                ObjectInputStream ois=new ObjectInputStream(socket.getInputStream());
                Message message=(Message) ois.readObject();

                //读取信息类型,做出相应业务
                if(message.getMesType().equals(MessageType.MESSAGE_GET_ONLINE_FRIEND)){
                    //返回在线用户列表
                    System.out.println("客户端"+message.getSender()+"要求返回所有在线用户列表");
                    String onlineUser=ManageServerConnectClientThread.getOnlineUser();
                    //创建一个新Message对象,返回信息
                    Message message2=new Message();
                    message2.setMesType(MessageType.MESSAGE_RET_ONLINE_FRIEND);
                    message2.setContent(onlineUser);
                    message2.setReceive(message.getSender());

                    //创建一个对象输出流,发送消息
                    ObjectOutputStream oos=new ObjectOutputStream(socket.getOutputStream());
                    oos.writeObject(message2);
                } else if (message.getMesType().equals(MessageType.MESSAGE_CLIENT_EXIT)) {
                    //用户退出登录
                    ManageServerConnectClientThread.removeServerConnectClientThread(message.getSender());
                    System.out.println(message.getSender()+"退出登录");
                    //关闭连接
                    socket.close();
                    //退出线程
                    break;
                } else if (message.getMesType().equals(MessageType.MESSAGE_COMM_MES)) {
                    //私聊消息
                    //转发消息给接受消息的用户

                    //先判断用户是否在线
                    if(ManageServerConnectClientThread.getServerConnectClientThread(message.getReceive())==null){//不在线
                        //判断离线消息集合中是否有其消息
                        if(OffLineMessage.getArrayList(message.getReceive())==null){//没有离线消息,则添加
                            ArrayList<Message> messages = new ArrayList<>();
                            messages.add(message);
                            //添加到离线消息集合
                            OffLineMessage.addOffLineDb(message.getReceive(),messages);
                        }else {
                            //根据用户名得到离线信息
                            ArrayList<Message> messages = OffLineMessage.getArrayList(message.getReceive());
                            //把离线消息放进消息集合中
                            messages.add(message);
                            //添加到离线消息集合
                            OffLineMessage.addOffLineDb(message.getReceive(),messages);
                        }
                    }
                    else {//在线
                        System.out.println("客户端" + message.getSender() + "给" + message.getReceive() + "发送消息");
                        ObjectOutputStream oos = new ObjectOutputStream(ManageServerConnectClientThread.getServerConnectClientThread(message.getReceive()).getSocket().getOutputStream());
                        oos.writeObject(message);
                    }
                } else if (message.getMesType().equals(MessageType.MESSAGE_TO_ALL_MES)) {
                    //群发消息
                    System.out.println(message.getSender()+"群发消息");
                    //用集合遍历
                    HashMap<String,ServerConnectClientThread>hm=ManageServerConnectClientThread.getHm();
                    Iterator<String> iterator = hm.keySet().iterator();
                    while(iterator.hasNext()){
                        //遍历集合取到用户名->得到线程->得到socket->得到对象输出流
                      String onlineUserId=iterator.next();

                      //判断是否为sender,不为sender则发送message
                        if(!onlineUserId.equals(message.getSender())){
                            ObjectOutputStream oos = new ObjectOutputStream(ManageServerConnectClientThread.getServerConnectClientThread(onlineUserId).getSocket().getOutputStream());
                            oos.writeObject(message);//发送消息
                        }
                    }
                } else if (message.getMesType().equals(MessageType.MESSAGE_FILE_MES)) {
                    //发送文件
                    //转发给receive
                    //先判断用户是否在线
                    if(ManageServerConnectClientThread.getServerConnectClientThread(message.getReceive())==null){//不在线
                        //判断离线消息集合中是否有其消息
                        if(OffLineMessage.getArrayList(message.getReceive())==null){//没有离线消息,则添加
                            ArrayList<Message> messages = new ArrayList<>();
                            messages.add(message);
                            //添加到离线消息集合
                            OffLineMessage.addOffLineDb(message.getReceive(),messages);
                        }else {
                            //根据用户名得到离线信息
                            ArrayList<Message> messages = OffLineMessage.getArrayList(message.getReceive());
                            //把离线消息放进消息集合中
                            messages.add(message);
                            //添加到离线消息集合
                            OffLineMessage.addOffLineDb(message.getReceive(),messages);
                        }
                    }
                    else {//在线
                        ObjectOutputStream oos = new ObjectOutputStream(ManageServerConnectClientThread.getServerConnectClientThread(message.getReceive()).getSocket().getOutputStream());
                        oos.writeObject(message);
                    }
                } else{
                    System.out.println("其他");
                }

            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            //后面会使用


        }
    }
}
